/*
* Tiled Map Editor, (c) 2004-2006
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* Adam Turk <aturk@biggeruniverse.com> Bjorn Lindeijer <bjorn@lindeijer.nl>
*/
package de.yaams.extensions.basemap.tiled.mapeditor.selection;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.util.prefs.Preferences;
import de.yaams.extensions.basemap.tiled.core.Tile;
import de.yaams.extensions.basemap.tiled.core.TileLayer;
import de.yaams.extensions.basemap.tiled.util.TiledConfiguration;
/**
* A layer used to keep track of a selected area.
*/
public class SelectionLayer extends TileLayer {
private Color highlightColor;
private Tile selTile;
private Area selection;
public SelectionLayer() {
init();
}
public SelectionLayer(int w, int h) {
super(w, h);
init();
}
private void init() {
Preferences prefs = TiledConfiguration.root();
try {
highlightColor = Color.decode(prefs.get("selectionColor", "#0000FF"));
} catch (NumberFormatException e) {
highlightColor = Color.blue;
}
selTile = new Tile();
selection = new Area();
}
/**
* Returns the selected area.
*
* @return the selected area
*/
public Area getSelectedArea() {
return selection;
}
/**
* Returns the bounds of the selected area.
*
* @return A Rectangle instance
* @see Area#getBounds()
*/
public Rectangle getSelectedAreaBounds() {
return selection.getBounds();
}
/**
* Adds the given area via a union
*
* @param area
* The Area to union with the current selection
* @see Area#add(java.awt.geom.Area)
*/
public void add(Area area) {
selection.add(area);
fillRegion(selection, selTile);
}
/**
* Deselects the given area. This substracts the given area from the
* existing selected area.
*
* @param area
* the Area to deselect
*/
public void subtract(Area area) {
clearRegion(area);
selection.subtract(area);
}
/**
* Sets the selected area to the given Shape.
*
* @param region
*/
public void selectRegion(Shape region) {
clearRegion(selection);
selection = new Area(region);
fillRegion(selection, selTile);
}
/**
* Selects only the given tile location (adds it to the selection if one
* exists)
*
* @param tx
* @param ty
*/
public void select(int tx, int ty) {
setTileAt(tx, ty, selTile);
Area a = new Area(new Rectangle2D.Double(tx, ty, 1, 1));
if (selection == null) {
selection = a;
} else {
if (!selection.contains(tx, ty)) {
selection.add(a);
}
}
}
/**
* Sets the highlight color.
*
* @param c
* the new highlight color to use when drawing this selection
*/
public void setHighlightColor(Color c) {
highlightColor = c;
}
/**
* Returns the highlight color.
*
* @return A Color instance of the highlight color
*/
public Color getHighlightColor() {
return highlightColor;
}
private void fillRegion(Area region, Tile fill) {
Rectangle bounded = region.getBounds();
for (int i = bounded.y; i < bounded.y + bounded.height; i++) {
for (int j = bounded.x; j < bounded.x + bounded.width; j++) {
if (region.contains(j, i)) {
setTileAt(j + bounds.x, i + bounds.y, fill);
} else {
setTileAt(j + bounds.x, i + bounds.y, null);
}
}
}
}
private void clearRegion(Area region) {
fillRegion(region, null);
}
/**
* Inverts the selected area.
*/
public void invert() {
selection.exclusiveOr(new Area(bounds));
for (int i = bounds.y; i < bounds.y + bounds.height; i++) {
for (int j = bounds.x; j < bounds.x + bounds.width; j++) {
if (selection.contains(j, i)) {
setTileAt(j, i, selTile);
} else {
setTileAt(j, i, null);
}
}
}
}
}